﻿using AddrDBContext.Model;
using ComClassLibrary;
using KeyboardArg;
using LogLib;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace AddressKeyBoard
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private DataService dataService = null;

        /// <summary>
        /// 当前选择地址的级别
        /// </summary>
        private CurrentSelectedLevel _selectedLevel = CurrentSelectedLevel.Streets;

        private int MaxLevel = 5;
  
        private KeyBoardArgs _keyboardArg;
        private int _btnHeight = 23;
        private int _btnWidth = 64;
        private int _btnHorDistance = 5; //水平间距
        private int _btnVerDistance = 5; //垂直间距
        private int _btnHorOffSet = 0;   //水平偏移
        private int _btnVerOffSet = 0;   //垂直偏移 
        private int _btnFontSize = 10;   //垂直偏移 

        private int _curSeletedIndex = 0;

        private string _curSeletedValue = "";

        private List<XButton> _listButtons = new List<XButton>();

        private List<XLabel> _listLabels = new List<XLabel>();

        private Dictionary<string, string> NameToAdressMap = new Dictionary<string, string>();

        /// <summary>
        /// 当前页面显示的文字元素和对应键值
        /// </summary>
        List<KeyValuePair<string, string>> listShowKeyValues = new List<KeyValuePair<string, string>>();

        /// <summary>
        /// 对于多级选项，保存当前选中的根元素名称
        /// </summary>
        private List<string> ListSelectedLevels = new List<string>();

        public MainWindow()
        {
            InitializeComponent();
        }

        public MainWindow(KeyBoardArgs KeyBoardArgs)
        {
            InitializeComponent();
            SetKeyBoardArg(KeyBoardArgs);
        }

        private void InitDataService()
        {
            dataService = new DataService();
            dataService.OpenDB();
            dataService.LoadStreets();
        }

        private void buttonClose_Click(object sender, RoutedEventArgs e)
        {
            if (_keyboardArg == null)
            {
                this.Close();
                return;
            }
            int uMsg = (int)MessageType.WM_COPYDATA;
            _keyboardArg.PassageType = SendMessageType.Response;
            _keyboardArg.Content = "";
            _keyboardArg.Command = "Cancel";
            string strMsgText = JsonHandler.ConvertToJsonString(_keyboardArg);
            byte[] data = System.Text.Encoding.UTF8.GetBytes(strMsgText);
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            cds.dwData = (IntPtr)uMsg;
            cds.cbData = data.Length;
            cds.lpData = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, cds.lpData, data.Length);
            Message.SendMessage(_keyboardArg.MsgReceiver, uMsg, 0, ref cds);
            cds.Free();
            this.Close();
            return;
        }

        private void buttonBackToLast_Click(object sender, RoutedEventArgs e)
        {
            if (_selectedLevel == CurrentSelectedLevel.Streets)
                return;
            _selectedLevel = (CurrentSelectedLevel)((int)_selectedLevel - 1);
            ListSelectedLevels.RemoveAt(ListSelectedLevels.Count - 1);
            CreatSelectButtons();
        }

        private bool ReadUIConfig(string fileName)
        {
            UIConfig config = new UIConfig(fileName);
            if (!config.OnReading())
            {
                MessageBox.Show("读取配置文件" + fileName + "失败: " + config.Error);
                return false;
            }
            _listButtons = config.ListButtons;
            _listLabels = config.ListLabels;
            return true;
        }

        public string ReadTitle(string path)
        {
            StreamReader sr = new StreamReader(path, Encoding.UTF8);
            string ret = "";
            string line = "";
            while ((line = sr.ReadLine()) != null)
            {
                ret += line;
            }
            return ret;
        }

        private void LoadCfg(string fileName)
        {
            //string str = IniFile.IniValue("setting", "Title", "", fileName);;
            string titleValue = IniFile.IniValue("setting", "Title", "", fileName);
            string titleFileName = string.Format("{0}\\{1}", System.IO.Path.GetDirectoryName(fileName), titleValue);
            if (File.Exists(titleFileName))
            {
                lblTips.Content = ReadTitle(titleFileName);
            }
            else
            {
                lblTips.Content = titleValue;
            }
            _btnHeight = int.Parse(IniFile.IniValue("setting", "ButtonHeight", "23", fileName));
            _btnWidth = int.Parse(IniFile.IniValue("setting", "ButtonWidtht", "64", fileName));
            _btnHorDistance = int.Parse(IniFile.IniValue("setting", "ButtonHorDistance", "5", fileName));
            _btnVerDistance = int.Parse(IniFile.IniValue("setting", "ButtonVerDistance", "5", fileName));
            _btnHorOffSet = int.Parse(IniFile.IniValue("setting", "ButtonHorOffSet", "0", fileName));
            _btnVerOffSet = int.Parse(IniFile.IniValue("setting", "ButtonVerOffSet", "0", fileName));
            _btnFontSize = int.Parse(IniFile.IniValue("setting", "ButtonFontSize", "10", fileName));
        }

        /// <summary>
        /// 加载小区地址的映射表
        /// </summary>
        private void LoadAdressMap(string xmlFile)
        {
            try
            {
                XDocument xmlDoc = XDocument.Load(xmlFile);
                XElement root = xmlDoc.Element("root");
                if (root == null)
                    return;
                NameToAdressMap.Clear();
                IEnumerable<XElement> elems = root.Elements("Level1");
                foreach (XElement e in elems)
                {
                    string key = e.Attribute("key").Value.Trim();
                    string roadName = e.Attribute("RoadName").Value.Trim();
                    string houseNumber = e.Attribute("HouseNumber").Value.Trim();
                    string adress = roadName + houseNumber + "号";
                    NameToAdressMap.Add(key, adress);
                }
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
        }

        public bool SetKeyBoardArg(KeyBoardArgs args)
        {
            _keyboardArg = args;
            _selectedLevel = CurrentSelectedLevel.Streets;
            ListSelectedLevels.Clear();
            MaxLevel = 5;

            //读配置文件
            string exeDir = System.AppDomain.CurrentDomain.BaseDirectory;
            string iniFileName = "";
            string uiConfigFile = "";
            string langCode = _keyboardArg.LanguageCode;
            if (string.IsNullOrEmpty(_keyboardArg.LanguageCode))
            {
                langCode = "zh-CN";
            }
            iniFileName = string.Format("{0}\\DIC\\{1}\\StandardAddress.ini", exeDir, langCode);
            if (!File.Exists(iniFileName))
            {
                MessageBox.Show($"字典文件{iniFileName}或{uiConfigFile}不存在");
                return false;
            }         
            LoadCfg(iniFileName);
            if (!string.IsNullOrEmpty(_keyboardArg.Title))
            {
                lblTips.Content = _keyboardArg.Title;
            }
            return true;
        }

        private void GetShowKeys(CurrentSelectedLevel level)
        {
            listShowKeyValues.Clear();
            switch (level)
            {
                case CurrentSelectedLevel.Streets:
                    foreach (TStreet street in dataService.Streets)
                    {
                        string key = street.Name;
                        string value = street.Code;
                        listShowKeyValues.Add(new KeyValuePair<string, string>(key, value));
                    }
                    break;
                case CurrentSelectedLevel.Communitys:
                    foreach (TCommunity community in dataService.Communitys)
                    {
                        string key = community.Name;
                        // 有多个同名小区
                        if(dataService.Communitys.Count(r=>r.Name == key) > 1)
                        {
                            key = $"{community.Name}({community.Road}{community.MPH}号)";
                        }
                        string value = community.Code;
                        listShowKeyValues.Add(new KeyValuePair<string, string>(key, value));
                    }
                    break;
                case CurrentSelectedLevel.Buildings:
                    foreach (string building in dataService.Buildings)
                    {
                        string key = building + "栋";
                        string value = building;
                        listShowKeyValues.Add(new KeyValuePair<string, string>(key, value));
                    }
                    break;
                case CurrentSelectedLevel.Unit:
                    foreach (string unit in dataService.Units)
                    {
                        string key = unit + "单元";
                        string value = unit;
                        listShowKeyValues.Add(new KeyValuePair<string, string>(key, value));
                    }
                    break;
                case CurrentSelectedLevel.Floor:
                    foreach (string floor in dataService.Floors)
                    {
                        string key = floor + "楼";
                        string value = floor;
                        listShowKeyValues.Add(new KeyValuePair<string, string>(key, value));
                    }
                    break;
                case CurrentSelectedLevel.Room:
                    foreach (string room in dataService.Rooms)
                    {
                        string key = room + "室";
                        string value = room;
                        listShowKeyValues.Add(new KeyValuePair<string, string>(key, value));
                    }
                    break;
                default:
                    break;
            }           
        }

        private void btn_click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            if(_selectedLevel == CurrentSelectedLevel.Streets && ListSelectedLevels.Count == 1)
            {
                ListSelectedLevels[0] = ((TextBlock)btn.Content).Text;
            }
            else
            {
                ListSelectedLevels.Add(((TextBlock)btn.Content).Text);
            }
            _curSeletedIndex = int.Parse(btn.Name.Split('_')[1]);
            _curSeletedValue = (string)btn.Tag;
            if ((int)_selectedLevel < MaxLevel)
            {
                switch (_selectedLevel)
                {
                    case CurrentSelectedLevel.Streets:
                        dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                        break;
                    case CurrentSelectedLevel.Communitys:
                        dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                        break;
                    case CurrentSelectedLevel.Buildings:
                        dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                        break;
                    case CurrentSelectedLevel.Unit:
                        dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                        break;
                    case CurrentSelectedLevel.Floor:
                        dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                        break;
                    case CurrentSelectedLevel.Room:
                        dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                        break;
                    default:
                        break;
                }
                _selectedLevel = (CurrentSelectedLevel)((int)_selectedLevel + 1);
                CreatSelectButtons();
            }
            else if(_selectedLevel == CurrentSelectedLevel.Room)
            {
                dataService.SetSelectedValue(_selectedLevel, _curSeletedIndex, _curSeletedValue);
                // 获取返回参数
                UpdateKeyboardArgs(btn);
                //点到最后一级后，发消息回主窗体，并且隐藏窗体
                SendMessage();
                this.Close();
            }          
        }

        private bool CreatCustomButtons()
        {
            try
            {
                canButtons.Children.Clear();
                for (int i = 0; i < listShowKeyValues.Count; i++)
                {
                    KeyValuePair<string, string> p = listShowKeyValues[i];
                    string Name = "button" + "_" + p.Value.ToString();
                    XButton xBtn = _listButtons.Find(r => r.Name.Equals(Name));
                    if (xBtn != null)
                    {
                        Button btn = xBtn.Creat(canButtons);
                        if (btn != null)
                        {
                            btn.Click += new RoutedEventHandler(btn_click);
                        }
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return false;
            }
        }

        private bool CreatCustomLabels()
        {
            if (_listLabels == null || _listLabels.Count == 0)
            {
                return true;
            }
            try
            {
                for (int i = 0; i < _listLabels.Count; i++)
                {
                    XLabel xLabel = _listLabels[i];
                    if (xLabel != null)
                    {
                        Label btn = xLabel.Creat(canButtons);
                    }
                }
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return false;
            }
        }

        private bool CreatDefaultButtons()
        {
            try
            {
                int maxHeight = 0;
                canButtons.Children.Clear();
                int i = 0;
                // 按钮当前垂直高度
                int curBtnVerticalHeight = 0;
                for (int  n = 0; n < listShowKeyValues.Count; n++)
                {
                    KeyValuePair<string, string> p = listShowKeyValues[n];
                    TextBlock tb = new TextBlock()
                    {
                        Text = p.Key,
                        FontSize = _btnFontSize,
                        TextWrapping = TextWrapping.Wrap,
                        TextAlignment = TextAlignment.Left
                    };
                    Button btn = new Button
                    {
                        Tag = p.Value,
                        Name = $"button_{n}",
                        Content = tb,
                        HorizontalContentAlignment = HorizontalAlignment.Left,
                        Height = _btnHeight,
                        Width = _btnWidth,
                        HorizontalAlignment = HorizontalAlignment.Left,
                        Margin = new Thickness(10, 10, 0, 0),
                        VerticalAlignment = VerticalAlignment.Top,
                        Visibility = Visibility.Visible,
                        FontSize = _btnFontSize,
                        Foreground = Brushes.DarkOliveGreen,
                        Background = Brushes.SeaShell,
                    };

                    btn.Click += new RoutedEventHandler(btn_click);
                    canButtons.Children.Add(btn);
                    double canvasLeft = (double)(i * (_btnWidth + _btnHorDistance));
                    if ((int)canvasLeft + _btnWidth + 5 > SelectionArea.Width)  //超出容器，另外起一行
                    {
                        i = 0;
                        curBtnVerticalHeight += (_btnVerDistance + _btnHeight);
                        canvasLeft = (double)(i * (_btnWidth + _btnHorDistance));
                    }
                    btn.SetValue(Canvas.LeftProperty, canvasLeft + (int)_btnHorOffSet);
                    btn.SetValue(Canvas.TopProperty, (double)(curBtnVerticalHeight + _btnVerOffSet));
                    if (maxHeight < curBtnVerticalHeight + _btnVerOffSet)
                    {
                        maxHeight = curBtnVerticalHeight + _btnVerOffSet;
                    }
                    i++;
                }
                if (maxHeight < 800)
                    canButtons.Height = 800;
                else
                    canButtons.Height = 3 * _btnHeight + maxHeight;
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                Console.WriteLine(e);
                return false;
            }
        }

        private void CreatSelectButtons()
        {
            GetShowKeys(_selectedLevel);
            if (listShowKeyValues == null || listShowKeyValues.Count == 0)
            {
                return;
            }
            CreatDefaultButtons();
            scrollViewer1.ScrollToVerticalOffset(0);
        }
    
        private void UpdateKeyboardArgs(Button btn)
        {
            //获取按钮的值
            string key = ((TextBlock)btn.Content).Text;
            string value = "";
            string[] array = btn.Name.Split('_');
            if (array.Length != 2)
            {
                MessageBox.Show("获取键值失败, 请检查字典配置是否正确.");
            }
            else
            {
                value = array[1];
            }
            _keyboardArg.PassageType = SendMessageType.Response;
            _keyboardArg.Content = key;
            KeyValuePair<string, string> p = listShowKeyValues.Find(r => r.Key.Equals(key));
            if (!string.IsNullOrEmpty(p.Value))
            {
                _keyboardArg.Code = p.Value;
            }
            else
            {
                _keyboardArg.Code = value;
            }
            _keyboardArg.Tag = dataService.theStreet.Code;
            _keyboardArg.FullContent = dataService.theAddr.XZ;
        }
      
        private bool SendMessage()
        {
            if (_keyboardArg.MsgReceiver == IntPtr.Zero)
            {
                MessageBox.Show("句柄错误", "句柄错误");
                return false;
            }
            int uMsg = (int)MessageType.WM_COPYDATA;
            string strMsgText = JsonHandler.ConvertToJsonString(_keyboardArg);
            byte[] data = System.Text.Encoding.UTF8.GetBytes(strMsgText);
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            cds.dwData = (IntPtr)uMsg;
            cds.cbData = data.Length;
            cds.lpData = Marshal.AllocHGlobal(data.Length);
            Marshal.Copy(data, 0, cds.lpData, data.Length);
            Message.SendMessage(_keyboardArg.MsgReceiver, uMsg, 0, ref cds);
            cds.Free();
            return true;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitDataService();
            CreatSelectButtons();
        }
    }
}
